package com.daniel.juc.lock;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * Condition 精准的通知和唤醒线程
 * A执行完调用B,B执行完调用C,C执行完调用A
 *
 * @author Daniel
 * @version V1.0
 * @date 2020/5/18 11:05
 */
public class PcDemo03 {
	public static void main(String[] args) {
		Data3 data = new Data3();

		new Thread(() -> {
			for (int i = 0; i < 10; i++) {
				data.printA();
			}
		}, "A").start();

		new Thread(() -> {
			for (int i = 0; i < 10; i++) {
				data.printB();
			}
		}, "B").start();

		new Thread(() -> {
			for (int i = 0; i < 10; i++) {
				data.printC();
			}
		}, "C").start();
	}

}

/**
 * 判断等待，业务，通知
 * 数字资源类
 */
class Data3 {
	private int number = 1;

	Lock lock = new ReentrantLock();
	// condition.await() //等待
	// condition.signalAll() //唤醒全部
	Condition condition1 = lock.newCondition();
	Condition condition2 = lock.newCondition();
	Condition condition3 = lock.newCondition();

	public void printA() {
		lock.lock();
		try {
			while (number != 1) {
				// 等待
				condition1.await();
			}

			number = 2;
			System.out.println(Thread.currentThread().getName() + "=>AAAAAA");
			// 唤醒指定的B
			condition2.signal();
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			lock.unlock();
		}
	}

	public void printB() {
		lock.lock();
		try {
			while (number != 2) {
				// 等待
				condition2.await();
			}

			number = 3;
			System.out.println(Thread.currentThread().getName() + "=>BBBBBB");
			// 唤醒指定的C
			condition3.signal();
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			lock.unlock();
		}
	}

	public void printC() {
		lock.lock();
		try {
			while (number != 3) {
				// 等待
				condition3.await();
			}

			number = 1;
			System.out.println(Thread.currentThread().getName() + "=>CCCCCC");
			// 唤醒指定的A
			condition1.signal();
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			lock.unlock();
		}
	}
}
